<template>
    <div id="Index">
        <div class="menu" v-if="userInfo.permissionIdList !== '0'">
            <img :src="userInfo.logo" class="logo_img" alt />

            <div style="flex: 1">
                <el-menu class="el-menu-demo" mode="horizontal" router :default-active="activeIndex" @select="handleSelect" v-if="activeMenu === 1">
                    <i v-show="menu_zy.length !== 0 && activeMenu === 2" class="el-icon-arrow-left cursor" style="font-size: 42px; color: #0cd9e8; margin-right: 8px" @click="changeMenu(1)"></i>
                    <template v-for="(item, index) in menu">
                        <el-menu-item v-if="item.type === 1" :key="item.key" :index="'/index/' + item.name">
                            <i :class="'iconfont ' + item.icon"></i>
                            <span slot="title">{{ item.label }}</span>
                        </el-menu-item>
                        <el-menu-item v-else :key="item.key" :index="'/index/' + item.name">
                            <i :class="'iconfont ' + item.icon"></i>
                            <span slot="title">{{ item.label }}</span>
                        </el-menu-item>
                    </template>
                    <i v-show="menu_zy.length !== 0 && activeMenu === 1" class="el-icon-arrow-right cursor" style="font-size: 42px; color: #0cd9e8" @click="changeMenu(2)"></i>
                </el-menu>
                <el-menu class="el-menu-demo" mode="horizontal" router :default-active="activeIndex" @select="handleSelect" v-if="activeMenu === 2">
                    <i v-show="menu_zy.length !== 0 && activeMenu === 2" class="el-icon-arrow-left cursor" style="font-size: 42px; color: #0cd9e8; margin-right: 8px" @click="changeMenu(1)"></i>
                    <template v-for="(item, index) in menu_zy">
                        <el-menu-item v-if="item.type === 1" :key="item.key" :index="'/index/' + item.name">
                            <i :class="'iconfont ' + item.icon"></i>
                            <span slot="title">{{ item.label }}</span>
                        </el-menu-item>
                        <el-submenu v-else :key="item.key" :index="index">
                            <template slot="title">
                                <i :class="'iconfont ' + item.icon"></i>
                                {{ item.label }}
                            </template>
                            <el-menu-item v-for="i in item.children" :key="i.name" :index="'/index/' + i.name">{{ i.label }}</el-menu-item>
                        </el-submenu>
                    </template>
                    <i v-show="menu_zy.length !== 0 && activeMenu === 1" class="el-icon-arrow-right cursor" style="font-size: 42px; color: #0cd9e8" @click="changeMenu(2)"></i>
                </el-menu>
            </div>
            <div class="menu_right">
                <img @click="toTxl" v-if="userInfo.user_id >= 1000" style="width: 22px; height: 22px" src="@/assets/iconfont/txl.png" alt />
                <img v-if="warnList.length === 0" style="width: 22px; height: 22px" src="@/assets/iconfont/warn.png" alt />
                <el-popover placement="bottom" trigger="hover" v-if="warnList.length !== 0">
                    <div class="userDel" style="max-height: 130px; overflow-y: auto">
                        <div v-for="item in warnList" :key="item.id" style="display: flex">
                            <div v-if="item.type === 'warn'" style="display: flex">
                                <el-tooltip class="item" effect="dark" :content="item.content" placement="left">
                                    <div @click="handle(item, 'see')" :style="`color: ${item.handle ? 'rgb(40, 151, 71)' : ''};width: 440px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;`">
                                        {{ item.content }}
                                    </div>
                                </el-tooltip>
                                <!-- <div @click="handle(item, 'to')" style="width: 70px; margin-left: 10px; color: #409eff">特征值分析</div> -->
                            </div>
                            <!-- <div @click="handle1(item)" v-if="item.type === 'notice'" style="display: flex">
                                <el-tooltip class="item" effect="dark" :content="item.content" placement="left">
                                    <div :style="`color: ${item.handle ? 'rgb(40, 151, 71)' : ''};width: 260px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;`">
                                        {{ item.content }}
                                    </div>
                                </el-tooltip>
                                <div style="width: 70px; margin-left: 10px; color: #409eff">查看工单</div>
                            </div>
                            <div v-if="item.type === 'state'" style="display: flex">
                                <el-tooltip class="item" effect="dark" :content="item.content" placement="left">
                                    <div @click="handle2(item)" :style="`color: ${item.handle ? 'rgb(40, 151, 71)' : ''};width: 100%;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;`">
                                        {{ item.content }}
                                    </div>
                                </el-tooltip>
                            </div> -->
                        </div>
                    </div>
                    <el-badge slot="reference" :hidden="warnListFilter.length === 0" :value="warnListFilter.length">
                        <img style="width: 22px; height: 22px" src="@/assets/iconfont/warn.png" alt />
                    </el-badge>
                </el-popover>
                <img @click="toAffair" v-if="xjList.length === 0 && userInfo.user_id >= 1000" style="width: 22px; height: 22px" src="@/assets/iconfont/shiwu.png" alt />
                <el-popover placement="bottom" trigger="hover" v-if="xjList.length !== 0 && userInfo.user_id >= 1000">
                    <div class="userDel" style="max-height: 130px; overflow-y: auto">
                        <div v-for="item in xjList" :key="item.id" style="display: flex">
                            <div @click="handlexj(item)" style="display: flex">
                                <div style="width: 220px">
                                    {{ item.content }}
                                </div>
                                <div style="width: 70px; margin-left: 10px; color: #409eff">{{ item.type }}</div>
                            </div>
                        </div>
                    </div>
                    <el-badge slot="reference" :hidden="xjList.length === 0" :value="xjList.length">
                        <img @click="toAffair" style="width: 22px; height: 22px" src="@/assets/iconfont/shiwu.png" alt />
                    </el-badge>
                </el-popover>
                <img @click="edit" style="width: 22px; height: 22px" src="@/assets/iconfont/shezhi.png" alt />
                <img src="@/assets/iconfont/return.png" style="width: 18px; height: 18px" alt="" v-if="userInfo.user_id == 130" @click="ZGJT_return" />
                <el-popover placement="bottom" trigger="hover" v-else>
                    <div class="userDel">
                        <div @click="userIsshow = true">个人中心</div>
                        <div @click="toStore">资料库</div>
                        <div @click="app">APP下载配置</div>
                        <div @click="getWarnCode">告警通知二维码</div>
                        <div @click="quitLogin">退出登录</div>
                    </div>
                    <img style="width: 22px; height: 22px" slot="reference" src="@/assets/iconfont/user.png" alt />
                </el-popover>
            </div>
            <el-dialog title="个人中心" :visible.sync="userIsshow" width="20%">
                <table class="dialog_table">
                    <tr>
                        <td>用户昵称：</td>
                        <td>{{ userInfo.nick_name }}</td>
                    </tr>
                    <tr>
                        <td>用户名：</td>
                        <td>{{ userInfo.user_name }}</td>
                    </tr>
                    <tr>
                        <td>角色：</td>
                        <td>{{ userInfo.role_name }}</td>
                    </tr>
                </table>
                <el-dialog width="26%" title="修改密码" :visible.sync="innerVisible" append-to-body>
                    <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm">
                        <el-form-item label="原密码" prop="age">
                            <el-input type="password" v-model="ruleForm.age"></el-input>
                        </el-form-item>
                        <el-form-item label="新密码" prop="pass">
                            <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input>
                        </el-form-item>
                        <el-form-item label="确认密码" prop="checkPass">
                            <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input>
                        </el-form-item>

                        <el-form-item>
                            <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button>
                            <el-button @click="resetForm('ruleForm')">重置</el-button>
                        </el-form-item>
                    </el-form>
                </el-dialog>
                <el-dialog width="26%" title="配置请求地址二维码" :visible.sync="urlVisible" append-to-body>
                    <el-form label-width="100px">
                        <el-form-item label="请求地址">
                            <el-input type="input" v-model="url"></el-input>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="setUrl">提交</el-button>
                        </el-form-item>
                    </el-form>
                </el-dialog>
                <div slot="footer" class="dialog-footer">
                    <div style="display: flex">
                        <el-button v-if="env" type="primary" plain @click="gxqd" size="small">前端</el-button>
                        <el-button v-if="env" type="primary" plain @click="gxhd" size="small">后端</el-button>
                        <el-button type="primary" plain @click="innerVisible = true" size="small">修改密码</el-button>
                        <el-button type="primary" plain @click="urlVisible = true" size="small">配置二维码</el-button>
                    </div>
                    <div v-if="env" style="display: flex; margin-top: 10px">
                        <el-select style="margin-right: 10px; width: 160px" placeholder="请选择打包分支" v-model="branch">
                            <el-option v-for="i in branchList" :key="i" :label="i" :value="i"></el-option>
                        </el-select>
                        <el-button v-if="env" size="small" type="primary" plain @click="getqdbranch">分支</el-button>
                        <el-button v-if="env" size="small" type="primary" plain @click="dabao">打包</el-button>
                    </div>
                </div>
            </el-dialog>
            <el-dialog width="600px" title="APP下载配置" :visible.sync="showQRCode" append-to-body>
                <div style="display: flex; color: #5ff2fa; font-size: 18px; justify-content: space-between">
                    <div>
                        <div>APP下载二维码</div>
                        <img style="height: 160px; width: 160px" :src="codeUrl" />
                    </div>
                    <div>
                        <div>配置请求地址二维码</div>
                        <img style="height: 160px; width: 160px" :src="downloadUrl" />
                    </div>
                </div>
            </el-dialog>
            <el-dialog width="240px" title="告警通知二维码" :visible.sync="showWarnCode" append-to-body>
                <img style="height: 160px; width: 160px" :src="warnUrl" />
            </el-dialog>
        </div>
        <div class="view_content">
            <transition name="slide-left">
                <router-view v-if="!$route.meta.isKeep"></router-view>
            </transition>
            <transition name="slide-left">
                <keep-alive>
                    <router-view v-if="$route.meta.isKeep"></router-view>
                </keep-alive>
            </transition>
        </div>
        <zy-form ref="zyform" :dialog="dialog" @set="setUser"></zy-form>
        <List ref="list" />
        <el-dialog v-if="isShow" width="80%" :visible.sync="isShow" :close-on-click-modal="false">
            <div style="width: 100%; height: 500px; position: relative">
                <mult-chart ref="multChart" :mulChart="mulChart" :sensorInfo="sensorInfo" />
                <div @click="wave" class="pointer" style="position: absolute; right: 0; top: 0; color: #409eff; font-size: 18px; font-weight: 600">诊断分析</div>
            </div>
        </el-dialog>
        <txl ref="txl"></txl>
        <affair ref="affair"></affair>
        <!-- <div style="position: fixed; right: 40px; bottom: 40px">
            <el-badge :is-dot="chatEnd">
                <img @click="openChat()" class="pointer" style="height: 40px" src="@/assets/Index/deepseek.png" />
            </el-badge>
        </div> -->
        <el-dialog class="chat" :title="智能助手" :visible.sync="showChat" top="10vh" width="80%" :lock-scroll="true">
            <div style="height: 80vh; display: flex">
                <div style="width: 220px; border: 1px solid #2969ed; padding: 20px 10px">
                    <div style="color: #00e4ff; text-align: center; font-size: 18px; font-weight: 700">工业设备预测性维护智能体</div>
                    <div style="margin-top: 20px">
                        <div :class="chatData.id === item.id ? 'f9edaa3c title select' : 'f9edaa3c title'" v-for="(item, index) in chatList" :key="item.id" @click="select(index)">
                            <div style="flex: 1; line-height: 28px; font-size: 16px; font-weight: bolder">
                                {{ item.title }}
                            </div>
                            <div>
                                <el-dropdown size="medium" trigger="click" @command="chatCommand($event, item.id)">
                                    <span class="el-dropdown-link">
                                        <i style="font-size: 22px" class="el-icon-more"></i>
                                    </span>
                                    <el-dropdown-menu slot="dropdown">
                                        <el-dropdown-item icon="el-icon-delete" command="d">删除对话</el-dropdown-item>
                                    </el-dropdown-menu>
                                </el-dropdown>
                            </div>
                        </div>
                    </div>
                </div>
                <div style="flex: 1; border: 1px solid #2969ed; padding: 20px">
                    <div style="display: flex; flex-direction: column; height: 100%">
                        <div v-if="chatData" style="flex: 1; display: flex; flex-direction: column; overflow-y: auto">
                            <div v-if="chatData.msg.length === 0" style="display: flex">
                                <img
                                    style="height: 36px; width: 36px; padding: 8px 3px 8px 5px; border-radius: 50px; border: 1px solid #4d6bfe; box-sizing: border-box; margin-top: 3px; margin-right: 4px"
                                    src="@/assets/Index/deepseek.png"
                                    alt=""
                                />
                                <div class="content">
                                    <div class="msg" v-text="'我是中云DeepSeek智能助手, 请告诉我您的需求'"></div>
                                </div>
                            </div>
                            <div v-for="item in chatData.msg" style="margin: 4px">
                                <div v-if="item.type === 'ai'" style="display: flex">
                                    <img
                                        style="height: 36px; width: 36px; padding: 8px 3px 8px 5px; border-radius: 50px; border: 1px solid #4d6bfe; box-sizing: border-box; margin-top: 6px; margin-right: 4px"
                                        src="@/assets/Index/deepseek.png"
                                        alt=""
                                    />
                                    <div class="content">
                                        <div class="time">{{ item.time }}</div>
                                        <div class="msg" v-text="item.context"></div>
                                    </div>
                                </div>
                                <div v-else style="display: flex; height: 60px; justify-content: flex-end; padding-left: 40px">
                                    <div class="content">
                                        <div class="time">{{ item.time }}</div>
                                        <div class="msg" v-text="item.context"></div>
                                    </div>
                                </div>
                            </div>
                            <div v-if="chatLoading" style="display: flex">
                                <img
                                    style="height: 36px; width: 36px; padding: 8px 3px 8px 5px; border-radius: 50px; border: 1px solid #4d6bfe; box-sizing: border-box; margin-top: 3px; margin-right: 4px"
                                    src="@/assets/Index/deepseek.png"
                                    alt=""
                                />
                                <div class="content">
                                    <div class="msg" id="text-container">思考中</div>
                                </div>
                            </div>
                        </div>
                        <div style="display: flex; margin-top: 5px">
                            <el-input v-model="chatInput" placeholder="请输入内容"></el-input>
                            <el-button style="margin-left: 10px" type="primary" @click="sendChat" :disabled="chatLoading">发送</el-button>
                        </div>
                    </div>
                </div>
            </div>
        </el-dialog>
    </div>
</template>

<script>
import Vue from 'vue'
import screenfull from 'screenfull'
import mqtt from 'mqtt/dist/mqtt'
import zyForm from '@/components/common/zyForm.vue'
import List from '@/views/BasicData/AlgorithmWarn/List.vue'
import drawEig from '@/components/drawEig'
import multChart from '@/views/Diagnosis/comList/multChart.vue'
import { dilution } from '@/views/Diagnosis/comList/config'
import { chartOptions, lineStyle } from '@/views/Diagnosis/config'
import txl from '@/components/txl/txl.vue'
import affair from '@/components/affair/affair.vue'
import { requestApi, sensorDetailsApi, getselfApi, getmenuApi, getWaveTagsApi, backstageTreeListApi, getEigenvalueTagsApi, dbmanageListApi, getmqttApi, cycleListApi, domainTagsListApi } from '@/requset/api'
import { deepClone } from '@/plugins/clone.js'
import { aes_encrypt, aes_decrypt } from '@/plugins/crypto.js'
import { mapState, mapMutations } from 'vuex'
import QRCode from 'qrcode'
import '@/assets/iconfont/css/iconfont.css'

const options = [
    {
        label: '一般',
        value: 1,
    },
    {
        label: '中等',
        value: 2,
    },
    {
        label: '严重',
        value: 3,
    },
    {
        label: '不提示',
        value: 4,
    },
]

export default {
    data() {
        var checkAge = (rule, value, callback) => {
            if (!value) {
                return callback(new Error('原密码不能为空'))
            } else {
                if (value != this.password) return callback(new Error('原密码错误'))
            }
        }
        var validatePass = (rule, value, callback) => {
            if (value === '') {
                callback(new Error('请输入密码'))
            } else {
                if (this.ruleForm.checkPass !== '') {
                    this.$refs.ruleForm.validateField('checkPass')
                }
                callback()
            }
        }
        var validatePass2 = (rule, value, callback) => {
            if (value === '') {
                callback(new Error('请再次输入密码'))
            } else if (value !== this.ruleForm.pass) {
                callback(new Error('两次输入密码不一致!'))
            } else {
                callback()
            }
        }
        return {
            chatEnd: false,
            chatLoading: false,
            showChat: false,
            chatToken: null,
            chatInput: '',
            chatList: [],
            chatData: null,
            mulChart: [],
            sys_eig: [],
            seriesArrs: [],
            activeIndex: '',
            activeMenu: 1,
            groupList: [],
            factoryList: [],
            value: 'a工厂',
            branchList: [],
            branch: '',
            userIsshow: false, //个人中心是否显示
            innerVisible: false, //修改密码
            userInfo: {
                menu: '',
                dataId: 0,
                permissionIdList: 1,
            },
            ruleForm: {
                pass: '',
                checkPass: '',
                age: '',
            },
            rules: {
                pass: [{ validator: validatePass, trigger: 'blur' }],
                checkPass: [{ validator: validatePass2, trigger: 'blur' }],
                age: [{ validator: checkAge, trigger: 'blur' }],
            },
            isFullscreen: false,
            menu: [],
            menu_zy: [],
            warnList: [],
            xjList: [],
            warn: {},
            notify: 4,
            speech: 4,
            mail: 4,
            message: 4,
            time: 0,
            urlVisible: false,
            url: '',
            dialog: {
                config: [
                    {
                        name: 'notify',
                        type: 'select',
                        label: '最低通知告警等级',
                        options,
                    },
                    {
                        name: 'speech',
                        type: 'select',
                        label: '最低语音告警等级',
                        options,
                    },
                    {
                        name: 'mail',
                        type: 'select',
                        label: '最低服务号告警等级',
                        options,
                    },
                    {
                        name: 'message',
                        type: 'select',
                        label: '最低短信告警等级',
                        options,
                    },
                ],
                form: {
                    notify: 4,
                    speech: 4,
                    mail: 4,
                    message: 4,
                },
                title: '用户设置',
                labelWidth: '140px',
            },
            isShow: false,
            showQRCode: false,
            showWarnCode: false,
            codeUrl: '',
            downloadUrl: '',
            warnUrl: '',
            device_id: null,
            sensor_id: null,
            date_time: [new Date(Date.now() - 86400000 * 1), new Date(Date.now())],
            sensorInfo: {},
            contextMenuData1: {
                // 菜单名称   同一界面必须唯一
                menuName: 'deviceEig',
                // 菜单显示的坐标位置
                axis: {
                    x: null,
                    y: null,
                },
                // 菜单选项
                menulists: [
                    {
                        fnHandler: 'downloadData',
                        btnName: '导出特征值数据',
                    },
                ],
            },
        }
    },
    components: {
        zyForm,
        List,
        drawEig,
        txl,
        affair,
        multChart,
    },
    computed: {
        ...mapState('userinfo', ['userself', 'login_token']),
        ...mapState('backstage', ['mqttConfig', 'backstageData']),
        password() {
            return JSON.parse(localStorage.getItem('userinfo')).password
        },
        warnListFilter() {
            return this.warnList.filter((item) => !item.handle)
        },
        env() {
            return process.env.NODE_ENV !== 'production'
        },
    },
    methods: {
        chatCommand(type, id) {
            if (id == 0) {
                return this.$message.error('对话还未开始，无法操作！')
            }
            if (type === 'd') {
                this.$confirm('确定要删除此对话', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning',
                })
                    .then(() => {
                        requestApi('post', 'chat/delete', { id }).then((res) => {
                            if (res.data.code == 0) {
                                this.$message({
                                    type: 'success',
                                    message: '删除成功',
                                })
                                this.getChat()
                            }
                        })
                    })
                    .catch(() => {
                        this.$message({
                            type: 'info',
                            message: '已取消删除',
                        })
                    })
            }
        },
        sendChat() {
            if (this.chatInput === '') {
                return this.$message.error('内容不能为空！')
            }
            let chatInput = this.chatInput
            this.chatInput = ''
            this.chatData.msg.push({
                type: 'user',
                time: this.dayjs().format('YYYY-MM-DD HH:mm:ss'),
                context: chatInput,
            })
            this.chatLoading = true

            let textArray = ['思考中。', '思考中。。', '思考中。。。', '思考中。。。。', '思考中。。。。。']
            let currentIndex = 0
            let intervalId = null

            intervalId = setInterval(() => {
                const container = document.getElementById('text-container')
                container.style.opacity = 0 // 设置透明度为 0（淡出效果）
                setTimeout(() => {
                    container.textContent = textArray[currentIndex]
                    container.style.opacity = 1 // 恢复透明度为 1（淡入效果）
                    currentIndex = (currentIndex + 1) % textArray.length // 循环索引
                }, 500) // 等待半秒后再显示新文字
            }, 1000)
            requestApi('post', 'chat/send', { token: this.chatToken, chatData: this.chatData }).then((res) => {
                this.chatData = res.data.data
                this.getChat()
                this.chatLoading = false
                this.chatEnd = !this.showChat
                clearInterval(intervalId)
                intervalId = null
            })
        },
        openChat() {
            if (!this.chatToken) {
                requestApi('get', 'chat/login').then((res) => {
                    this.chatToken = res.data.data
                })
                this.getChat()
            }
            this.chatEnd = false
            this.showChat = !this.showChat
        },
        getChat() {
            requestApi('post', 'chat/getlist', { user_id: sessionStorage.getItem('user_id') }).then((res) => {
                if (res.data.data.length) {
                    this.chatList = res.data.data.map((item) => {
                        item.msg = JSON.parse(item.msg)
                        return item
                    })
                    if (!this.chatData) this.chatData = this.chatList[0]
                } else {
                    this.chatList = [
                        {
                            id: 0,
                            user_id: sessionStorage.getItem('user_id'),
                            title: 'DeepSeek智能助手',
                            msg: [],
                        },
                    ]
                    this.chatData = this.chatList[0]
                }
            })
        },
        select(index) {
            this.chatData = this.chatList[index]
        },
        changeMenu(e) {
            if (e == 1) {
                this.activeMenu--
                this.$nextTick(() => this.$router.push('/index/home'))
            } else {
                this.activeMenu++
                this.$nextTick(() => this.$router.push('/index/xj_device'))
            }
        },

        setUrl() {
            localStorage.setItem('url', this.url)
            this.urlVisible = false
        },
        toTxl() {
            this.$refs.txl.doOpen(false)
        },
        toAffair() {
            this.$refs.affair.doOpen(false)
        },
        toStore() {
            this.$router.push(`/store`)
        },
        app() {
            QRCode.toDataURL(`http://xz.demo.com/down/APP.apk`, (err, codeUrl) => {
                if (err) {
                    console.error(err)
                } else {
                    this.codeUrl = codeUrl
                    let url = localStorage.getItem('url') || 'https://phm.demo.com:4112'
                    QRCode.toDataURL(url, (err, downloadUrl) => {
                        if (err) {
                            console.error(err)
                        } else {
                            this.showQRCode = true
                            this.downloadUrl = downloadUrl
                        }
                    })
                }
            })
        },
        getWarnCode() {
            let phonenumber = sessionStorage.getItem('phonenumber')
            const pattern = /^1\d{10}$/
            if (pattern.test(phonenumber)) {
                requestApi('get', 'http://phm.demo.com/getWarnURL?phonenumber=' + phonenumber).then((res) => {
                    this.warnUrl = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' + res.data
                    this.showWarnCode = true
                })
            } else {
                this.$message.error('用户需先绑定手机号')
            }
        },
        gxqd() {
            requestApi('get', 'https://phm.demo.com/api/openapi/gxqd', null, true).then((res) => {
                if (res.data.code === 0) {
                    alert('前端更新成功')
                } else {
                    alert(res.data.msg)
                }
            })
        },
        gxhd() {
            requestApi('get', 'https://phm.demo.com/api/openapi/gxhd', null, true).then((res) => {
                if (res.data.code === 0) {
                    alert('后端更新成功')
                } else {
                    alert(res.data.msg)
                }
            })
        },
        dabao() {
            let url = 'http://192.168.1.109:5600/api/openapi/buildexe?branch=' + this.branch
            window.open(url, '_blank')
        },
        ZGJT_return() {
            window.location.href = 'uniwebview://close'
        },
        //映射方法
        ...mapMutations('userinfo', ['setUserself']),
        ...mapMutations('backstage', [
            'eigenvalueGetlist',
            'getBackstage',
            'getDeviceType',
            'getMenuList',
            'getMenuType',
            'getSensorTreeData',
            'getCycleList',
            'getRoleList',
            'getBackstageList',
            'getMqttConfig',
            'domainTagsGetlist',
            'waveTagsGetlist',
            'getSensorType',
            'getWavcacq',
            'getEigtag',
            'getWavetag',
            'getAlgorithmData',
        ]),
        //退出登录
        quitLogin() {
            this.$confirm('确认退出登录?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
            })
                .then(() => {
                    // this.$message({
                    //     type: 'success',
                    //     message: '已退出登录!',
                    // })
                    localStorage.removeItem('token')
                    sessionStorage.clear()
                    this.$nextTick(() => {
                        this.$router.push('/login')
                    })
                })
                .catch(() => {
                    this.$message({
                        type: 'info',
                        message: '已取消退出',
                    })
                })
        },
        //查询用户个人信息
        getself() {
            getselfApi().then((res) => {
                this.setUserself(res.data)
                this.userInfo = res.data
                let id = res.data.dataId
                this.backstageTreeList(id)
                sessionStorage.setItem('role_id', this.userInfo.role_id)
                sessionStorage.setItem('userLevel', this.userInfo.type)
                sessionStorage.setItem('user_name', this.userInfo.user_name)
                sessionStorage.setItem('user_id', this.userInfo.user_id)
                sessionStorage.setItem('phonenumber', this.userInfo.phonenumber)
                sessionStorage.setItem('nick_name', this.userInfo.nick_name)
                sessionStorage.setItem('menu', this.userInfo.menu)
                sessionStorage.setItem('operate', this.userInfo.operate)
                sessionStorage.setItem('logo', this.userInfo.logo)
                sessionStorage.setItem('permissionIdList', this.userInfo.permissionIdList)
                if ([1, 2, 3, 4].includes(this.userInfo.notify)) {
                    this.notify = this.userInfo.notify
                }
                if ([1, 2, 3, 4].includes(this.userInfo.speech)) {
                    this.speech = this.userInfo.speech
                }
                if ([1, 2, 3, 4].includes(this.userInfo.mail)) {
                    this.mail = this.userInfo.mail
                }
                if ([1, 2, 3, 4].includes(this.userInfo.message)) {
                    this.message = this.userInfo.message
                }
                this.getmenu(this.userInfo.menu)
                // this.getxjList()
            })
        },
        getmenu(menu) {
            function buildTree(data, parentId = null) {
                let tree = []

                data.forEach((item) => {
                    if (item.parent === parentId) {
                        let children = buildTree(data, item.id)
                        if (children.length) {
                            item.children = children
                        }

                        item.value = item.id
                        delete item.id
                        tree.push(item)
                    }
                })
                return tree
            }
            getmenuApi().then((res) => {
                let list = []
                let list_zy = []
                res.data.data
                    .filter((item) => this.userInfo.menu.split(',').includes(item.id.toString()))
                    .forEach((item) => {
                        if (item.type === 1 || item.type === 2) {
                            item.children = []
                            item.id < 100 ? list.push(item) : list_zy.push(item)
                        } else {
                            if (item.id < 100) {
                                try {
                                    list.find((i) => item.parent == i.id).children.push(item)
                                } catch (error) {}
                            } else {
                                list_zy.find((i) => item.parent == i.id).children.push(item)
                            }
                        }
                    })
                this.menu = list
                this.menu_zy = list_zy
                list = res.data.data
                    .filter((item) => item.type === 1 || item.type === 2)
                    .map((item) => ({
                        value: item.id,
                        label: item.label,
                        children: item.type === 1 ? undefined : [],
                    }))
                res.data.data
                    .filter((item) => item.type === 3)
                    .forEach((item) => {
                        let parent = list.find((i) => i.value === item.parent)
                        if (parent && parent.hasOwnProperty('children'))
                            parent.children.push({
                                value: item.id,
                                label: item.label,
                            })
                    })
                this.getMenuList(list)

                this.getMenuType(res.data.data)
            })
        },
        // 获取后台节点树形结构
        backstageTreeList(id) {
            backstageTreeListApi(id).then((res) => {
                if (res.data.code == 0) {
                    this.getSensorTreeData(res.data.data)
                    let data = deepClone(res.data.data)
                    this.getBackstage(data)
                }
            })
        },
        // 获取设备类型
        deviceTypeGetlis() {
            requestApi('post', 'deviceType/getlist').then((res) => {
                if (res.data.code == 0) {
                    this.getDeviceType(res.data.data)
                }
            })
        },
        // 获取特征值类型
        getEigenvalueTags() {
            getEigenvalueTagsApi().then((res) => {
                if (res.data.code == 0) {
                    this.eigenvalueGetlist(res.data.data)
                }
            })
        },
        getEigtag_() {
            requestApi('post', 'sys_eig/getlist', { page: 1 }, false).then((res) => {
                if (res.data.code == 0) {
                    this.sys_eig = res.data.data
                    this.getEigtag(res.data.data)
                }
            })
        },
        getWavetag_() {
            requestApi('post', 'sys_wave/getlist', { page: 1 }, false).then((res) => {
                if (res.data.code == 0) {
                    this.getWavetag(res.data.data)
                }
            })
        },
        getAlgorithmData_() {
            requestApi('post', 'trouble/getModel', { page: 1, size: 9999 }).then((res) => {
                if (res.data.code == 0) {
                    this.getAlgorithmData(res.data.data)
                }
            })
        },
        cycleList() {
            cycleListApi().then((res) => {
                if (res.data.code == 0) {
                    this.getCycleList(res.data.data)
                }
            })
        },
        roleList() {
            requestApi('post', `role/getlist`).then((res) => {
                if (res.data.code == 0) {
                    this.getRoleList(
                        res.data.data.map((item) => {
                            item.name = item.desc
                            return item
                        }),
                    )
                }
            })
        },
        backstageList() {
            requestApi('get', 'backstage/getAll').then((res) => {
                if (res.data.code == 0) {
                    this.getBackstageList(res.data.data)
                }
            })
        },
        domainTagsList() {
            domainTagsListApi().then((res) => {
                if (res.data.code == 0) {
                    this.domainTagsGetlist(
                        res.data.data.map((item) => {
                            item.name = item.value
                            return item
                        }),
                    )
                }
            })
        },
        waveTagsList() {
            getWaveTagsApi().then((res) => {
                if (res.data.code == 0) {
                    this.waveTagsGetlist(res.data.data)
                }
            })
        },
        sensorTypeTagsList() {
            requestApi('post', 'sensorType/getlist').then((res) => {
                if (res.data.code == 0) {
                    this.getSensorType(res.data.data)
                }
            })
        },
        getmqtt() {
            getmqttApi().then((res) => {
                if (res.data.code == 0) {
                    let config = JSON.parse(aes_decrypt(res.data.data))
                    this.getMqttConfig(config)
                    config.clientId = Math.random().toString(16).substring(2, 8)
                    Vue.prototype.$mqtt = mqtt.connect(config['url'], config)
                    let that = this
                    this.$mqtt
                        .on('connect', function () {
                            console.log('mqtt连接')
                            // that.getWarn()
                        })
                        .on('reconnect', function () {
                            if (that.time < 3) {
                                that.time++
                                console.log('mqtt第' + that.time + '次重连')
                            } else {
                                console.log('超出重连次数,mqtt结束')
                                that.$mqtt.end()
                            }
                        })
                        .on('error', function () {
                            console.log('mqtt错误')
                            that.$mqtt.end()
                        })
                        .on('end', function () {
                            console.log('mqtt结束')
                            that.$mqtt = null
                        })
                }
            })
        },
        Wavcacq() {
            requestApi('post', 'waveacq' + `/getlist`, { page: 1 }, false)
                .then((res) => {
                    if (res.data.code == 0) {
                        this.getWavcacq(res.data.data)
                    }
                })
                .finally(() => {
                    this.loading = false
                })
        },
        handleUser() {},
        //修改密码
        changePwd() {},
        submitForm(formName) {
            this.$refs[formName].validate((valid) => {})
            if (this.ruleForm.age === this.password && this.ruleForm.pass === this.ruleForm.checkPass) {
                requestApi('post', 'user/password', { id: this.userInfo.user_id, password: aes_encrypt(this.ruleForm.pass) }).then((res) => {
                    if (res.data.code === 0) {
                        this.$message.success('修改密码成功，请重新登录')
                        localStorage.removeItem('token')
                        sessionStorage.clear()
                        this.$nextTick(() => {
                            this.$router.push('/login')
                        })
                    }
                })
            }
        },
        // 重置表单
        resetForm(formName) {
            this.$refs[formName].resetFields()
        },
        screen() {
            screenfull.toggle()
            this.isFullscreen = !this.isFullscreen
        },
        handleSelect(e) {
            this.setActMenu()
        },
        // getWarn() {
        // let mqttConfig = this.mqttConfig
        // if (mqttConfig.warn_topic === undefined || mqttConfig.warn_topic === '') {
        //     return
        // }
        // this.topic = mqttConfig.warn_topic
        // let that = this
        // that.getWarnList()
        // that.$mqtt.subscribe(that.topic, { qos: 1 })
        // this.$mqtt.on('message', function (top, message) {
        //     if (that.topic === top) {
        //         let a = JSON.parse(message.toString())
        //         let dataId = that.userInfo.dataId
        //         that.getWarnList()
        //         if (dataId === 0 || a['group_id'] === dataId || a['company_id'] === dataId || a['factory_id'] === dataId || a['zone_id'] === dataId) {
        //             if (a.warn_level >= that.notify) {
        //                 that.$notify({
        //                     message: '收到' + a.content + '告警！请在右上角提示中查看处理',
        //                     type: 'warning',
        //                     position: 'bottom-right',
        //                 })
        //             }
        //             if (a.warn_level >= that.speech) {
        //                 let speakAudio = new window.SpeechSynthesisUtterance('开始语音播报')
        //                 speakAudio.lang = 'zh-CN' //使用语言
        //                 speakAudio.rate = 1 //播放语速
        //                 speakAudio.volume = 1 //播放音量
        //                 let context = a.content.slice(0, a.content.lastIndexOf('|'))
        //                 speakAudio.text = ('收到' + context.slice(0, context.lastIndexOf('|')).replace(/\|/g, '').replace('#', '号') + '告警').split('').join(' ') //改变播放文本内容
        //                 speakAudio.onend = function () {
        //                     window.speechSynthesis.speak(speakAudio) // 当语音播放结束时重新播放
        //                 }
        //                 window.speechSynthesis.speak(speakAudio) //控制播放
        //             }
        //         }
        //     }
        // })
        // },
        makeWarnPort(a) {
            let { pred_time, device_id } = a
            // 解析输入的日期时间字符串
            const inputDate = this.dayjs(pred_time)
            const prevDate = inputDate.subtract(2, 'day')
            const nextDate = inputDate.add(2, 'day')
            const prevStr = prevDate.format('YYYY-MM-DD HH:mm:ss')
            const nextStr = nextDate.format('YYYY-MM-DD HH:mm:ss')
            let times = [prevStr, nextStr]
            requestApi(
                'post',
                'report/down/sys',
                {
                    type_: 1,
                    device_ids: [device_id],
                    times,
                },
                true,
            )
        },
        getWarnList() {
            requestApi('post', 'algorithm_notice/getlist', {}).then((res) => {
                this.warnList = res.data.data
            })
        },

        getxjList() {
            if (this.userInfo.user_id >= 1000)
                requestApi('post', 'mqtt/xj', { name: this.userInfo.nick_name }).then((res) => {
                    this.xjList = res.data.data
                })
        },
        rule(id) {
            if (this.userInfo.dataId === 0) return true
            else if (this.backstageData.length !== 0) {
                let list = []
                function getChildren(backstageData, list) {
                    list.push(backstageData.value)
                    if (backstageData.type === 'zone' || !backstageData.children) return
                    backstageData.children.forEach((item) => {
                        getChildren(item, list)
                    })
                }
                this.backstageData.forEach((item) => {
                    getChildren(item, list)
                })
                return list.includes(id)
            } else return false
        },
        handle(val, type) {
            // window.speechSynthesis.cancel()
            this.isShow = false
            if (!val.handle) {
                val.handle = 1
                requestApi('post', 'algorithm_notice/edit', val).then((res) => {
                    this.getWarnList()
                })
            }
            if (type === 'see') {
                this.$refs.list.doOpen(val, true)
            } else {
                let { warn_source, content } = val
                let name = this.getFeatureKey(content)
                this.device_id = Number(val.device_id)
                let sensor_id = Number(val.sensor_id)
                let time = val.sent_time
                let time_start = new Date(time).getTime() / 1000 - 3600 * 6
                let time_end = new Date(time).getTime() / 1000 + 3600 * 6
                this.$set(this.date_time, 0, time_start)
                this.$set(this.date_time, 1, time_end)
                this.warn = val
                sensorDetailsApi(sensor_id).then((res) => {
                    if (res.data.code == 0) {
                        this.sensorInfo = res.data.data
                        this.isShow = true
                        let { id, address, port, proj_no, single, sensor_name } = this.sensorInfo
                        this.mulChart.length = 0
                        let options = deepClone(chartOptions('datetime'))
                        this.seriesArrs = []
                        let arr1 = this.getChannel(address)
                        const obj = {
                            saddr: arr1[0],
                            channel: arr1[1],
                            sport: port,
                            single,
                            proj_no,
                            stime: time_start,
                            etime: time_end,
                        }
                        let arrN = []
                        let arrZ = []
                        let arrX = []
                        let arrY = []
                        let split = val.content.includes('X_') ? 'X_' : val.content.includes('Y_') ? 'Y_' : 'Z_'
                        let eig = this.sys_eig.find((item) => item.nickname === val.content.split(split)[1])
                        let { nickname, vibration, name } = eig
                        obj.eigkey = vibration == 1 ? [nickname] : single == 1 ? [`Z.${nickname}`] : [`Z.${nickname}`, `Y.${nickname}`, `X.${nickname}`]
                        requestApi('post', 'diag/eiges', obj, true).then((res) => {
                            if (res.data.code == 0) {
                                let list = dilution(res.data.data)
                                if (list.length > 0) {
                                    list.forEach((e) => {
                                        let { id } = e
                                        var timestamp = Number(id) * 1000
                                        if (vibration == 1) {
                                            arrN.push([timestamp, e[nickname] !== undefined ? e[nickname] : null])
                                        } else if (vibration == 3) {
                                            if (single == 1) arrN.push([timestamp, e['Z'][nickname] !== undefined ? e['Z'][nickname] : null])
                                            else {
                                                try {
                                                    if (split === '_Z') {
                                                        arrZ.push([timestamp, e['Z'][nickname] !== undefined ? e['Z'][nickname] : null])
                                                    } else if (split === '_X') {
                                                        arrX.push([timestamp, e['X'][nickname] !== undefined ? e['X'][nickname] : null])
                                                    } else {
                                                        arrY.push([timestamp, e['Y'][nickname] !== undefined ? e['Y'][nickname] : null])
                                                    }
                                                } catch (error) {
                                                    arrZ = arrX = arrY = []
                                                }
                                            }
                                        }
                                    })
                                }
                                try {
                                    if (arrN.length != 0)
                                        this.seriesArrs.push({
                                            data: arrN,
                                            name: sensor_name + name,
                                            id,
                                        })
                                    if (arrX.length != 0)
                                        this.seriesArrs.push({
                                            data: arrX,
                                            name: sensor_name + '轴向' + name,
                                            id,
                                        })
                                    if (arrZ.length != 0)
                                        this.seriesArrs.push({
                                            data: arrZ,
                                            name: sensor_name + '垂直' + name,
                                            id,
                                        })
                                    if (arrY.length != 0)
                                        this.seriesArrs.push({
                                            data: arrY,
                                            name: sensor_name + '水平' + name,
                                            id,
                                        })
                                } catch (error) {}
                                options.series = []
                                this.seriesArrs.forEach((e, i) => {
                                    options.series.push(
                                        Object.assign(
                                            {
                                                data: e.data,
                                            },
                                            lineStyle(e.name + ' ' + eig.unit),
                                        ),
                                    )
                                })
                                options.legend.enabled = true
                                options.title.text = ``
                                let id_ = 'id'
                                this.$set(this, 'mulChart', [{ id: id_, type: 'eig', loading: true }])
                                this.$nextTick(() => {
                                    this.$refs.multChart.draw(options, id_)
                                })
                            }
                        })
                    }
                })
            }
        },
        getChannel(address) {
            const parts = address.split('_')
            const firstNumber = parts[0]
            const secondNumber = parts[1] ? parts[1] : 0
            return [firstNumber.toString(), secondNumber.toString()]
        },
        handle1(item) {
            this.$router.push(`/index/expdig/notice?device_name=${item.content.split('设备')[1].split('工单')[0]}`)
        },
        handlexj(item) {
            if (this.$route.name === item.menu) {
                this.$message({
                    type: 'error',
                    message: '已在诊断分析页面,不可重复跳转!',
                })
            } else {
                this.$router.push(`/index/${item.menu}?id=${item.number}`)
            }
        },
        handle2(item) {
            if (!item.handle) {
                item.handle = 1
                requestApi('post', 'algorithm_notice/edit', item).then((res) => {
                    this.getWarnList()
                })
            }
        },
        edit() {
            this.dialog.form.notify = this.notify
            this.dialog.form.speech = this.speech
            this.dialog.form.mail = this.mail
            this.dialog.form.message = this.message
            this.dialog.form.id = this.userInfo.user_id
            this.$refs.zyform.openDialog('change')
        },
        setUser(obj) {
            requestApi('post', 'user/edit', obj).then((res) => {
                this.notify = obj.notify
                this.speech = obj.speech
                this.mail = obj.mail
                this.message = obj.message
                this.$refs.zyform.closeDialog()
            })
        },
        getFeatureKey(str) {
            var lastIndex = str.lastIndexOf('|')
            if (lastIndex !== -1) {
                return str.substring(lastIndex + 1)
            } else {
                return ''
            }
        },
        wave() {
            let val = this.warn
            this.isShow = false
            if (this.$route.name === 'diagnosis') {
                this.$message({
                    type: 'error',
                    message: '已在图谱页面,不可重复跳转!',
                })
            } else {
                let { content } = val
                let name = ''
                name = this.getFeatureKey(content)
                this.$router.push(`/index/expdig/diagnosis?device_id=${val.device_id}&time=${val.sent_time}&sensor_id=${val.sensor_id}&key=${name}`)
            }
        },
        getqdbranch() {
            requestApi('get', 'http://192.168.1.109:5600/api/openapi/getqdbranch', null, false).then((res) => {
                if (res.data.code === 0) {
                    this.branchList = res.data.data
                }
            })
        },
        setActMenu() {
            let home = this.$route.path.includes('home')
            let xj_ = this.$route.path.includes('xj_')
            if (home) {
                this.$set(this, 'activeIndex', this.$route.path)
            }
            if (!home && !xj_) {
                let result = this.$route.path.replace(/\/[^\/]*$/, '')
                this.$set(this, 'activeIndex', result)
                this.activeIndex = result
            }
        },
    },
    created() {
        this.url = localStorage.getItem('url') || 'https://phm.demo.com:4112'
        this.$EventBus.$on('undateMenu', () => {
            this.getself()
        })
        this.$EventBus.$on('undateMqtt', () => {
            this.getmqtt()
        })
        this.$EventBus.$on('undateWarn', () => {
            this.getWarnList()
        })
        this.$EventBus.$on('undatexj', () => {
            this.getxjList()
        })
        this.$EventBus.$on('undateRole', () => {
            this.roleList()
        })
        this.$EventBus.$on('undateBackstageTreeList', () => {
            this.backstageTreeList(this.userInfo.dataId)
        })
        this.getself()
        this.activeIndex = this.$route.path
        this.deviceTypeGetlis()
        this.getEigenvalueTags()
        this.getmqtt()
        this.cycleList()
        this.roleList()
        this.backstageList()
        this.domainTagsList()
        this.waveTagsList()
        this.sensorTypeTagsList()
        this.Wavcacq()
        this.getEigtag_()
        this.getWavetag_()
        this.getAlgorithmData_()
        this.getWarnList()
        setTimeout(() => {
            this.getWarnList()
        }, 10000)
    },

    beforeDestroy() {
        this.$mqtt.unsubscribe(this.topic)
        this.$mqtt.end()
        this.$mqtt = null
    },
    update() {
        // this.setActMenu()
    },
    watch: {
        $route: {
            handler(val, oldval) {
                this.setActMenu()
            },
            deep: true,
        },
    },
    mounted() {},
}
</script>

<style lang="less" scoped>
.slide-left-enter {
    opacity: 0;
    transform: rotateY(180deg);
}

.slide-left-enter-active {
    transition: all 600ms;
}

.slide-left-leave-to {
    opacity: 0;
    transform: rotateY(-180deg);
    // transition: translate3d(100%,0,-100%)
}

#Index {
    width: 100%;
    height: 100%;
}

.menu {
    position: relative;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    // background-color: red;
    background-image: linear-gradient(#11629a, #114071, #11629a);

    .logo_img {
        margin-left: 15px;
        max-height: 24px;
    }

    .el-menu {
        height: 40px;
        background-color: transparent !important;
        z-index: 9;
        justify-content: space-between;
        display: flex;
    }

    .menu_right {
        height: 100%;
        width: 130px;
        margin-right: 5px;
        display: flex;
        align-items: center;
        justify-content: space-around;

        img:hover {
            cursor: pointer;
        }
    }
}

.userDel {
    div {
        height: 32px;
        color: #0cd9e8;
        text-align: left;
        line-height: 32px;
    }

    div:hover {
        background-color: #007bff;
        cursor: pointer;
    }
}

.icon {
    height: 20px !important;
    margin-top: 13px;
}

.view_content {
    position: relative;
    width: 100%;
    height: calc(100% - 40px);
    overflow: hidden;
}

.view_content::-webkit-scrollbar {
    width: 0 !important;
}

.dialog_table {
    font-size: 18px;
    color: white;

    tr {
        width: 100%;
        height: 30px;
        // background-color: red;
        margin-bottom: 6px !important;
    }
}

::-webkit-scrollbar {
    width: 0;
    height: 0;
}

@media screen and (max-width: 1540px) {
    // .iconfont {
    //     display: none !important;
    // }

    ::v-deep {
        .el-submenu__title,
        .el-menu-demo .el-menu-item {
            max-width: 125px !important;
            // margin-right: 8px;
        }
    }
}

@media screen and (max-width: 1320px) {
    .logo_img {
        display: none !important;
    }
}

.title {
    display: flex;
    align-items: center;
}

.f9edaa3c {
    height: 38px;
    cursor: pointer;
    --ds-focus-ring-border-radius: 14px;
    border-radius: 12px;
    align-items: center;
    padding: 0 10px;
    font-size: 14px;
    display: flex;
    position: relative;
    color: #fff;
}

.select {
    background-color: #409eff !important;
}

.avatar {
    width: 45px;
    height: 45px;
    background-image: url(@/assets/Home/logo.96bf599c.svg);
    background-size: 100% 100%;
    background-repeat: no-repeat;
    padding: 3px 5px;
}

.content {
    flex: 1;
    display: flex;
    flex-direction: column;
    padding: 3px 5px;

    .time {
        font-size: 12px;
        padding: 3px 0px;
        color: #225bac;
    }

    .msg {
        background: #9babc321;
        color: #33e6ff;
        padding: 10px;
        border-radius: 5px;
        line-height: 18px;
    }

    .tips {
        background-color: #9babc321;
        padding: 10px;
        margin-top: 5px;
        width: fit-content;
        border-radius: 5px;

        ul {
            list-style-type: disc;
            padding: 5px 12px;

            li {
                line-height: 1.5;
                cursor: pointer;
                color: #1ba3ff;
            }
        }
    }
}

.chat {
    ::v-deep {
        .el-dialog__header {
            display: none;
        }
        .el-dialog__body {
            padding: 0;
            border-radius: 5px;
        }
    }
}
#text-container {
    transition: opacity 0.5s ease-in-out; /* 添加淡入淡出效果 */
}
</style>
